from typing import Dict, List, Optional
from metagpt.actions import Action


class AnalyzeTopic(Action):
    """分析文章主题的行为"""
    
    def __init__(self):
        super().__init__(name="分析主题", 
                         description="分析用户提供的主题，确定目标受众、内容类型和情感基调")
    
    async def run(self, content_requirements: str) -> Dict:
        """分析写作需求"""
        analysis_prompt = f"""请分析以下写作需求：
        {content_requirements}
        
        请提供以下方面的分析：
        1. 目标受众：谁将阅读这篇文章？他们的特点是什么？
        2. 内容类型：这是一篇技术文章、观点文章、教程还是其他类型？
        3. 情感基调：文章应该采用什么样的语气？专业、友好、严肃还是轻松？
        4. 关键点：文章应该覆盖哪些关键点？
        5. 建议结构：推荐的文章结构是什么？
        
        以JSON格式返回结果，包含以上所有字段。
        """
        
        result = await self._aask(analysis_prompt)
        # 将结果解析为结构化数据
        try:
            import json
            return json.loads(result)
        except:
            # 如果解析失败，返回原始文本
            return {"raw_analysis": result}


class CreateOutline(Action):
    """创建文章大纲的行为"""
    
    def __init__(self):
        super().__init__(name="创建大纲", 
                         description="根据主题分析创建详细的文章大纲")
    
    async def run(self, analysis: Dict) -> List[Dict]:
        """根据分析结果创建大纲"""
        outline_prompt = f"""
        根据以下主题分析信息，创建一个详细的文章大纲：
        
        分析结果：{analysis}
        
        请提供一个结构化的大纲，包含：
        1. 文章标题
        2. 引言部分要点
        3. 主体部分的各个章节和子章节
        4. 每个章节应该包含的关键点
        5. 结论部分要点
        
        以列表形式返回大纲，使每个部分和子部分清晰可辨。
        """
        
        result = await self._aask(outline_prompt)
        # 处理返回结果，将其结构化
        try:
            import json
            return json.loads(result)
        except:
            # 如果解析失败，尝试简单的文本处理
            sections = []
            current_section = {"title": "", "content": []}
            
            for line in result.split('\n'):
                line = line.strip()
                if not line:
                    continue
                    
                if line.startswith('#'):  # 判断是否为标题
                    if current_section["title"]:  # 保存之前的部分
                        sections.append(current_section)
                        current_section = {"title": "", "content": []}
                    current_section["title"] = line.lstrip('#').strip()
                else:
                    current_section["content"].append(line)
            
            if current_section["title"]:  # 添加最后一个部分
                sections.append(current_section)
                
            return sections


class WriteContent(Action):
    """撰写文章内容的行为"""
    
    def __init__(self):
        super().__init__(name="撰写内容", 
                         description="根据大纲撰写完整的文章内容")
    
    async def run(self, analysis: Dict, outline: List[Dict]) -> str:
        """根据大纲和分析撰写文章内容"""
        # 构建提示词，包含分析和大纲信息
        content_prompt = f"""
        请根据以下分析和大纲撰写一篇完整的文章：
        
        主题分析：{analysis}
        
        文章大纲：{outline}
        
        请注意以下要求：
        1. 文章应符合分析中确定的目标受众、内容类型和情感基调
        2. 文章应该流畅自然，逻辑清晰
        3. 段落之间应有良好的过渡
        4. 使用具体的例子和数据支持观点
        5. 确保文章结构遵循提供的大纲
        
        请直接撰写完整的文章内容，包括标题、引言、主体和结论部分。
        """
        
        return await self._aask(content_prompt)


class ReviewContent(Action):
    """审查和优化文章的行为"""
    
    def __init__(self):
        super().__init__(name="审查内容", 
                         description="审查文章内容并提出改进建议")
    
    async def run(self, analysis: Dict, content: str) -> Dict:
        """审查文章内容并提出改进建议"""
        review_prompt = f"""
        请审查以下文章，并提供改进建议：
        
        主题分析：{analysis}
        
        文章内容：
        {content}
        
        请从以下方面进行评估：
        1. 内容是否符合主题分析中的要求
        2. 结构是否清晰逻辑
        3. 语言表达是否流畅
        4. 论点是否有力且有支持
        5. 拼写和语法是否正确
        
        请提供具体的改进建议，以JSON格式返回，包含以下字段：
        - overall_rating：总体评分（1-10）
        - strengths：文章的优点列表
        - weaknesses：文章的弱点列表
        - suggestions：具体的改进建议列表
        - revised_content：修改后的文章内容（如有必要）
        """
        
        result = await self._aask(review_prompt)
        
        try:
            import json
            return json.loads(result)
        except:
            return {"raw_review": result} 